package com.rtuwrapper.processing;

public abstract class ModbusDataType<T> {

    private byte[] address = new byte[2];
    private byte[] value = new byte[4];

    ModbusDataType() {
    }

    void setAddress(int addr) {
        intToBytes(addr, address);
    }

    void setValue(int val) {
        intToBytes(val, value);
    }

    void setFloatValue(float val) {
        floatToBytes(val, value);
    }

    void setValueBoolean(boolean val) {
        if (val) {
            value[0] = (byte) 0xff;
        } else {
            value[0] = (byte) 0x00;
        }
        value[1] = (byte) 0x00;
    }

    int getValueInt() {
        return intFromBytes(value);
    }

    float getValueFloat() {
        return floatFromBytes(value);
    }

    // 返回16位有符号整数（将16位无符号转为有符号整数）
    int getValueInteger16() {
        int value16 = intFromBytes(value);
        if(value16 > 0x7fff){
            value16 = value16 - 0x10000;
        }
        return value16;
    }

    private int intFromBytes(byte[] bytes) {
        return ((bytes[0] & 0xff) << 8 | (bytes[1] & 0xff));
    }

    private float floatFromBytes(byte[] bytes) {
        int ival = ((bytes[0] & 0xff) << 24 | (bytes[1] & 0xff) << 16 | (bytes[2] & 0xff) << 8 | (bytes[3] & 0xff));
        return Float.intBitsToFloat(ival);
    }

    private void intToBytes(int val, byte[] holder) {
        holder[0] = (byte) (0xff & (val >> 8));
        holder[1] = (byte) (0xff & val);
    }

    private void floatToBytes(float val, byte[] holder) {
        int ival = Float.floatToIntBits(val);
        holder[0] = (byte) (0xff & (ival >> 24));
        holder[1] = (byte) (0xff & (ival >> 16));
        holder[2] = (byte) (0xff & (ival >> 8));
        holder[3] = (byte) (0xff & ival);
    }

    public int getAddress() {
        return intFromBytes(address);
    }

    public byte[] getAddressBytes() {
        return address;
    }

    public byte[] getValueBytes() {
        return value;
    }

    public abstract T getValue();

}
